#!/usr/bin/env python
   
#from Extract_packages import *
#from XmlGenerate import *

from subprocess import *
from shutil import move
from shutil import copytree

import os, sys
import os.path

from ivic.core import Config, project_path, Utils
from ivic.vsequencer.Extract_packages import *
from ivic.vsequencer.XmlGenerate import *
from ivic.vsequencer.Config import *

#try:
#    from ivic.core import *
#    from ivic.vsequencer.Extract_packages import *
#    from ivic.vsequencer.XmlGenerate import *
#    from ivic.vsequencer.Config import *  
#except:
#    sys.path.insert(0, os.getcwd())
#    from ivic.core import *
#    set_rundebug()
#    from ivic.vsequencer.XmlGenerate import * 
#    from ivic.vsequencer.Config import *
#    from ivic.vsequencer.Extract_packages import *
    
    
config = VSequencerConfig()

#=========================================================================
def usage():
    print """Usage: vsquencer <soft_name> <source_path> <dest_path>
                           
        <soft_name>   --  Name of soft which need sequenced
        
        <root_path>   --  Work Path for the soft sequence
        
        <pakage_path> --  Path of the soft package  

    """
    
#=========================================================================
#
#=========================================================================

def initlog(logfile):
    import logging
    
    logger = logging.getLogger()
    hdlr = logging.FileHandler(logfile)
    formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
    hdlr.setFormatter(formatter)
    logger.addHandler(hdlr)
    logger.setLevel(logging.NOTSET)
    
    return logger

#=========================================================================
#
#=========================================================================

class Sequencer():
    def __init__(self, soft_name, source_path, dest_path):
        self.soft_name = soft_name
        self.source_path = source_path
        self.dest_path = dest_path

#=========================================================================    
    
    def extract_packages(self):     
        """ 
            Tools required - tar, bunzip2, unzip, ar, zcat, rpm2cpio
            Command calls should be safe only our generated path names 
            are passed in
        """
        
        # change the working folder
#        if not os.path.exists(self.root_path):
#            command = " ".join(['mkdir -p', self.root_path])
#            os.system(command)
#        os.chdir(self.root_path)
        
#        try:
#            os.makedirs(self.soft_name + "/usr/lib")
#        except:
#            pass
#        os.chdir(self.soft_name)
	self.__execute_extract_command("pack %s %s %s 1024" %(self.soft_name,self.source_path,self.dest_path))
        
        # Zip archives
#        self.__execute_extract_command("UNP=$(find %s/*.tgz 2>/dev/null) &&\
#                 for UN in $UNP; do tar zxvf $UN ; done" % (self.package_path))
#        self.__execute_extract_command("UNP=$(find %s/*.tar.gz 2>/dev/null) &&\
#                 for UN in $UNP; do tar zxvf $UN ; done" % (self.package_path))
#        self.__execute_extract_command("UNP=$(find %s/*.tbz 2>/dev/null) &&\
#                 for UN in $UNP; do bunzip2 -c $UN | tar -xvf - ; done" % (self.package_path))
#        self.__execute_extract_command("UNP=$(find %s/*.tar.bz2 2>/dev/null) &&\
#                 for UN in $UNP; do bunzip2 -c $UN | tar -xvf - ; done" % (self.package_path))
#        self.__execute_extract_command("UNP=$(find %s/*.tbz2 2>/dev/null) &&\
#                 for UN in $UNP; do bunzip2 -c $UN | tar -xvf - ; done" % (self.package_path))
#        self.__execute_extract_command("UNP=$(find %s/*.zip 2>/dev/null) &&\
#                 for UN in $UNP; do unzip $UN ; done" % (self.package_path))
                
        # Debain packages
#        self.__execute_extract_command("UNP=$(find %s/*.deb 2>/dev/null) &&\
#                 for UN in $UNP; do ar p $UN data.tar.gz | zcat | tar xv ; done" % (self.package_path))   
                
        # RPM packages
        # TODO: we need a better rpm extra
        # http://www.rpm.org/max-rpm/s1-rpm-file-format-rpm-file-format.html
 #       self.__execute_extract_command("UNP=$(find %s/*.rpm 2>/dev/null) &&\
 #                for UN in $UNP; do rpm2cpio < $UN | cpio -i -d --verbose ; done" % (self.package_path))
        
#=========================================================================                

    def __execute_extract_command(self,command):
        logger = initlog("/tmp/extract.log")
	print command
        p = Popen(command, stdout=PIPE, shell=True, stderr=STDOUT)
        for line in p.stdout:
            logger.info(line.split("\n"))
        p.stdout.close()
        p.wait()
        
#=========================================================================
    
    def xml_generate(self):
        """
            generate the xml for the sequenced soft
        """
        
#        lddinfo_generate(self.soft_name, self.root_path)
#        lddlib = getLddLib(self.soft_name, self.root_path)
#        print lddlib
        
#        print os.path.join(self.root_path, self.soft_name, "usr/lib")
#        libfile_dict = getLibfiles(os.path.join(self.root_path, self.soft_name, "usr/lib"))
        
        
        xmldescription = xmlGenerate(self.soft_name)   
        print xmldescription
        try:
            file = open(os.path.join(self.source_path, self.soft_name + ".xml"), \
                        "w")
#            file = open("/tmp/"+ soft + "/" + soft+".xml","w")
            print >> file, xmldescription
     
        except IOError, e:
             print >> sys.stderr, "File could not be opened", e
             sys.exit(1)
             
        file.close()
#        lddfile = os.path.join(self.root_path,self.soft_name,"usr/bin/lddinfo")
#        cmd = "".join(["rm -f ",lddfile])
#        os.system(cmd)
#=========================================================================

    def soft_publish(self):
        softpath = self.source_path
	srcpath = os.path.join(self.dest_path, self.soft_name + ".isoe")
        xmlfile = os.path.join(softpath, self.soft_name + ".xml")
        metaFile = config.metaFile
        releasePath = config.releasePath
#        if os.path.exists(releasePath):
#            cmd = "rm -rf " + releasePath
#            os.system(cmd)
        try:
            move(xmlfile, metaFile)
        except:
            pass 
	command = "cp "+srcpath+" "+releasePath
	try:
            os.system(command)
	except:
	    pass
#=========================================================================
#
#========================================================================= 
  
    def portal_register(self,softname,category):
        class CaCertError(Exception): pass
        class CertError(Exception): pass
        
        args = {
                'name'        :   '',
                'snapshot'    :   '',
                'category'    :   '',
                'os'          :   '',
                'price'       :   '',
                'description' :   '', 
        }
        args['name'] = softname
        args['category'] = category
        args['os'] = 'Linux'
	args['run']= softname
        
        ca_cert = config.ca_cert
        cert = config.cert
        
        while not os.path.exists(ca_cert):
            ca_cert = raw_input('%s not exists, please enter the path of ca_cert: ' % ca_cert)
        
        while not os.path.exists(cert):
            cert = raw_input('%s not exists, please enter the path of ca_cert: ' % cert)
        
#        try:
#            if not os.path.exists(ca_cert):
#                raise CaCertError, ("CA cert not exists.")
#            if not os.path.exists(cert):
#                raise CertError, ("Cert not exists.")
#        
#        except CaCertError,e:
#            QtGui.QMessageBox.warning(self, "Ca cert Error",
#                                unicode(e))
#            return
#        
#        except CertError,e:
#            QtGui.QMessageBox.warning(self, "Cert Error",
#                                unicode(e))
#            return
        
        rest_request = ''
        for x in args.keys():
            rest_request = rest_request + '<%s>%s</%s>' % (x, args[x], x)
        rest_request = '<software>%s</software>' % rest_request
        url = config.url
            
        header_file = run('mktemp')
              
       
        curl_args = '-X POST -H "Content-Type: text/xml" -H "Accept: text/xml" --cert %s --cacert %s -d "%s" --dump-header  %s %s' % (cert, ca_cert, rest_request,header_file,url)
        result = os.system('curl %s ' % curl_args)
        

#=========================================================================
#
#=========================================================================
def run(cmd):
    """
    Run a shell command and return stdout.
    """
    from subprocess import Popen, PIPE, STDOUT
    p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
    output = p.stdout.read()
    return output.strip()


def error(msg):
    """
    Display an error message and exit.
    """
    # print msg
    # sys.exit()
    raise Exception, msg
#=========================================================================
#
#=========================================================================
def do_gui_main(soft_name, source_path, dest_path):
    """
    vsequencer Main
    """
    
    sequencer = Sequencer(soft_name, source_path, dest_path)
    sequencer.extract_packages()
    
#    try:
#       if os.path.exists(os.path.join(sequencer.root_path, sequencer.soft_name, "usr/games")):
#           os.rename(os.path.join(sequencer.root_path, sequencer.soft_name, "usr/games"), \
#                      os.path.join(sequencer.root_path, sequencer.soft_name, "usr/bin"))
#    except OSError, err:
#        error("reanme the dirctory 'games' to 'bin' :%s" % str(err))
#        return None
    
    sequencer.xml_generate()

#=========================================================================

def do_main(soft_name, source_path, dest_path):
    """
    vsequencer Main
    """
    
    sequencer = Sequencer(soft_name, source_path, dest_path)
    sequencer.extract_packages()
    categories = {
                1   :   'Accessories',
                2   :   'Games',
                3   :   'Graphics',
                4   :   'Internet',
                5   :   'Multimedia',
                6   :   'Office', 
                7   :   'Programming',
                8   :   'System',
                9   :   'Other'
    }
    sequencer.xml_generate()
    option = raw_input("-->Do you want to publish the soft? please enter Y or N. ")
    while not option.upper().strip() in ('N','Y'):
        option = raw_input("Illegal input,you should only input one of letters in  'y','Y','n','N',.\n")
    if option.upper() == 'Y':
        sequencer.soft_publish()
        print 'The soft you want to pulish belong which category ? '
        for i in range(len(categories)):
            print "   ",i+1,':',categories[i+1]
    
        index = int(raw_input('please enter the category index: '))
        while index not in categories.keys():
            index = int(raw_input('Illegal index,please re-enter the category index: '))
        print categories[index]
        category = categories[index]
        sequencer.soft_publish()
        sequencer.portal_register(soft_name,category)
        print "xml publish to %s/%s.xml" %(config.metaFile,soft_name)
        print "soft publish to %s/%s" %(config.releasePath,soft_name)
#=========================================================================
#
#=========================================================================

def main():
    if len(sys.argv) == 4:
        soft_name = sys.argv[1]
        source_path = sys.argv[2]
        dest_path = sys.argv[3]
        do_main(soft_name, source_path, dest_path)
    else:
        usage()

#=========================================================================
#
#=========================================================================
